/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sd_proj1.mainProgram;

import sd_proj1.interfaces.*;

/**
 *
 * @author Pedro Costa Correia - 32795
 * @author Valter Pedro Lopes Vicente - 39360
 */
public class Craftsman extends Thread {

	/**
	 *  Valor máximo de armazenamento de produtos na oficina.
	 *
	 *    @serialField MAX
	 */
	private final int MAX = 10;
	/**
	 *  Identificação do artesão.
	 *
	 *    @serialField craftsmanId
	 */
	private int craftsmanId;
	/**
	 *  Instanciação da interface do artesão implementada no monitor da oficina.
	 *
	 *    @serialField workshop
	 */
	private ICraftsman workshop;
	/**
	 *  Instanciação da interface do artesão implementada no estado geral.
	 *
	 *    @serialField general
	 */
	private ICraftsmanFifo general;

	/**
	 *  Instanciação da thread do artesão.
	 *
	 * @param craftsmanId Identificação do artesão.
	 * @param workshop Interface do artesão associada ao monitor da oficina.
	 * @param general Interface do artesão associada ao estado geral.
	 */
	public Craftsman(int craftsmanId, ICraftsman workshop, ICraftsmanFifo general) {
		this.craftsmanId = craftsmanId;
		this.workshop = workshop;
		this.general = general;
	}

	/**
	 * Ciclo de vida da thread do artesão.
	 */
	@Override
	public void run() {
		int np;																/* Quantidade de produtos armazenados na oficina */
		boolean alert;													/* Baixo nível de matérias primas na oficina */
		while (!workshop.endOperCraftsman(craftsmanId)) {
			alert = workshop.collectMaterials(craftsmanId);				/* O artesão retira as matérias primas que necessita para fazer o produto */
			if (alert) {
				general.primeMaterialsNeeded(craftsmanId);		/* O artesão avisa a dona de que são necessárias mais matérias primas */
				workshop.backToWork(craftsmanId);					/* O artesão regressa à sua actividade */
			}
			workshop.prepareToProduce(craftsmanId);					/* O artesão senta-se e prepara-se para trabalhar o novo produto */
			shapingItUp();												/* O artesão trabalha sobre o novo produto */
			np = workshop.goToStore(craftsmanId);						/* O artesão guarda o produto terminado */
			if (np == MAX) {											/* O artesão verifica se é altura de transferir os produtos */
				general.batchReadyForTransfer(craftsmanId);		/* O artesão notifica a dona para esta vir buscar os produtos terminados */
			}
			workshop.backToWork(craftsmanId);						/* O artesão regressa à sua actividade */
		}
	}

	/**
	 *  O artesão trabalha sobre o produto (operação interna).
	 */
	private void shapingItUp() {
		try {
			sleep((long) (1 + 100 * Math.random()));
		} catch (InterruptedException e) {
		}
	}
}
